class_name Missile
extends BaseEffectorObject

enum MissileLineType
{
	DashedLine, # 虚线
	SolidLine, # 实线
}
#region 属性
@export var mid_point_t:float = 0.5
@export var line_type:MissileLineType
@export var is_scale:bool = false
@export var is_scale_reverse:bool = false
@export var end_scale:Vector2
@export_group("虚线相关")
@export var dashed_point_scene:PackedScene
@export var dashed_point_count:int = 10
@export_group("")
@export_group("实线相关")
@export var solid_line_color:Color
@export var solid_point_count:int = 100
@export_group("")
@export_group("引用")
@export var line_2d:Line2D
@export var path_2d:Path2D
@export var path_follow_2d:PathFollow2D
@export_group("")
@export_group("额外方法")
@export var before_follow_additional_effects:Array[AdditionalEffect]
@export var completed_follow_additional_effects:Array[AdditionalEffect]
@export_group("")
@export var target_pos:Vector2
var active:bool = false
var creater:Entity
var duration:float
var control_point_pos:Vector2
var follow_tween:Tween
var path:Array = []
var dashed_line_points:Array[Node2D] = []
var args:Dictionary = {}
#endregion
#region 字段
#endregion
#region 信号
#endregion

#region 基类方法
#endregion
#region 公共方法
func init(creater:Entity,duration:float = 1,args:Dictionary = {}):
	self.creater = creater
	self.duration = duration
	self.args = args
	if line_type == MissileLineType.DashedLine:
		for i in range(dashed_point_count):
			var ins:Node2D = dashed_point_scene.instantiate()
			ins.visible = false
			add_child(ins)
			dashed_line_points.append(ins)
		line_2d.visible = false
		line_2d.clear_points()
	else:
		line_2d.visible = true
		line_2d.default_color = solid_line_color
		line_2d.clear_points()
	Utils.array_call_method(before_follow_additional_effects,"init",{Target = creater,Owner = self})
	Utils.array_call_method(completed_follow_additional_effects,"init",{Target = creater,Owner = self})
	active = true
func get_target_pos() -> Vector2:
	return target_pos
func calc_control_point():
	control_point_pos = (global_position + get_target_pos())/2 + Vector2.UP * (get_target_pos() - global_position).length() * mid_point_t
func get_line_path() -> Array:
	path.clear()
	calc_control_point()
	if line_type == MissileLineType.DashedLine:
		path = BezierUtil.get_bezier_path(global_position,control_point_pos,get_target_pos(),dashed_point_count)
	else:
		path = BezierUtil.get_bezier_path(global_position,control_point_pos,get_target_pos(),solid_point_count)
	return path
func start_follow():
	end_follow()
	follow_tween.finished.connect(func():
		Utils.array_call_method(before_follow_additional_effects,"excute")
		)
	follow_tween = get_tree().create_tween()
	follow_tween.tween_property(path_follow_2d,"progress_ratio",1,duration)
	follow_tween.finished.connect(func():
		Utils.array_call_method(completed_follow_additional_effects,"excute")
		)
func end_follow():
	if is_instance_valid(follow_tween) and follow_tween.is_valid():
		follow_tween.stop()
func destroy():
	queue_free()
#endregion
#region 私有方法
#endregion
#region 生命周期函数
func _process(delta: float) -> void:
	if not active:
		return
	var path:Array = get_line_path()
	if line_type == MissileLineType.DashedLine:
		if path_2d.curve == null:
			path_2d.curve = Curve2D.new()
		path_2d.curve.clear_points()
		for i in range(path.size()):
			dashed_line_points[i].global_position = path[i]
			dashed_line_points[i].visible = true
			path_2d.curve.add_point(path[i])
	else:
		if path_2d.curve == null:
			path_2d.curve = Curve2D.new()
		path_2d.curve.clear_points()
		for i in range(path.size()):
			path_2d.curve.add_point(path[i])
		line_2d.points = path_2d.curve.get_baked_points()
#endregion
